`ifndef CP0Defines_SVH
`define CP0Defines_SVH
`include "defines.svh"

typedef struct packed {
    logic WrongAddrInIF;            //地址错例外——取值
    logic WrongAddrInDataWr;        //地址错例外——数据写
    logic WrongAddrInDataRd;        //地址错例外——数据读
    logic Overflow;                 //整形溢出
    logic Syscall;                  //系统调用
    logic Break;                    //断点例外
    logic ReservedInstr;            //保留指令例外
    logic Interrupt;                //中断
    logic Eret;                     //例外返回
} ExceptionType;

typedef struct packed {
    logic HardwareInterrupt1;       //硬件中断例外1
    logic HardwareInterrupt2;       //硬件中断例外2
    logic HardwareInterrupt3;       //硬件中断例外3
    logic HardwareInterrupt4;       //硬件中断例外4
    logic HardwareInterrupt5;       //硬件中断例外5
    logic HardwareInterrupt6;       //硬件中断例外6
} AsynExceptionType;

//系统控制器CP0寄存器的地址
`define CP0IndexAddr 5'b00000
`define CP0EntryLo0Addr 5'b00010
`define CP0EntryLo1Addr 5'b00011
`define CP0BadVAddrAddr 5'b01000
`define CP0CountAddr 5'b01001
`define CP0EntryHiAddr 5'b01010
`define CP0CompareAddr 5'b01011
`define CP0StatusAddr 5'b01100
`define CP0CauseAddr 5'b01101
`define CP0EPCAddr 5'b01110
`define CP0ConfigAddr 5'b10000

//Excode编码,课本上P341
`define ExcCodeInt 5'b00000         //中断
`define ExcCodeAdEL 5'b00100        //地址错例外（读数据或取指令）
`define ExcCodeAdES 5'b00101        //地址错例外（写数据）
`define ExcCodeSys 5'b01000         //系统调用例外
`define ExcCodeBp 5'b01001          //断点例外
`define ExcCodeRI 5'b01010          //保留指令例外
`define ExcCodeOv 5'b01100          //算数溢出例外

`define NoException 9'b0

//对IsExceptionorEret而言
`define NoExceptionandEret 2'b00
`define IsException        2'b01
`define IsEret             2'b10

`endif